<?php

require_once('ExceptionDAO.php');

/**
 * DAO para as operações de banco de dados referentes ao controle de acesso.
 *
 */
class DAOControleAcesso extends CI_Model {


    /**
     * Verifica se um grupo tem determinada permiss�o.
     * @param $idUsuario
     * @param $idAcao
     * @param $parametro
     * @return bool
     */
    public function temGrupoAcao($idGrupo, $idAcao) {
        try {

            $sql = "
				SELECT
					COUNT(*) > 0
				FROM
					si_grupo g JOIN si_grupo_acao ga ON (g.ID_GRU = ga.ID_GRU)
				WHERE
				  	g.ATIVO_GRU = 1 AND g.ID_GRU = :idGrupo	AND	(ga.ID_ACA = :idAcao)
					AND CURDATE() BETWEEN ga.dataInicial AND ga.dataFinal";
            $st = $this->getConexao()->prepare($sql);
            $st->bindValue(":idGrupo", $idGrupo);
            $st->bindValue(":idAcao", $idAcao);
            $st->execute();
            return ($st->fetchColumn() == TRUE);
        } catch (Exception $e) {
            return FALSE;
        }
    }

    /**
     * Verifica se um usu�rio tem permiss�o de executar a��es
     * em um curso.
     * @param $idUsuario
     * @param $idCurso
     * @return bool
     */
    public function temPermissaoCurso($idUsuario, $idCurso) {
        //TODO Verificar se esta condicao est� correta
        if (TOAluno::isMatriculaAluno($idUsuario)) {
            $dao = new DAOUsuarioAluno();
            return $this->isAlunoCurso($idUsuario, $idCurso);
            //	throw new ExceptionPermissao("Permiss�o negada.");
        } else {
            $dao = new DAOUsuarioServidor();
            return $dao->temPermissaoCurso($idUsuario, $idCurso);
        }
    }

    private function isAlunoCurso($matricula, $idCurso) {
        $dao = new DAOAluno();
        $aluno = new TOAluno();
        $aluno->matricula = $matricula;
        $aluno = $dao->consultarAlunoPorMatricula($aluno);
        return $aluno->curso->codigoCurso == $idCurso;
    }

    /**
     * Verifica se al�m de um usu�rio possuir determinada
     * permiss�o essa permiss�o inclui determinado par�metro.
     * 
     * @param $idUsuario
     * @param $idAcao
     * @param $parametro
     * @return bool
     */
    public function temParametroAcao($idUsuario, $idAcao, $parametro) {
        if (TOAluno::isMatriculaAluno($idUsuario)) {
            return FALSE;
        } else {
            $dao = new DAOUsuarioServidor();
            return $dao->temParametroAcao($idUsuario, $idAcao, $parametro);
        }
    }

    /**
     * Obtem o(s) parametro de uma determinada a��o
     * 
     * @param int $acao o id da a��o
     * @return o parametro caso exista, null caso n�o exista paramentro
     * @throws ExceptionDAO caso n�o tenha o grupo e a��o
     */
    public function getParametroPorAcao($grupo, $acao) {
        try {
            // reutiliza o SQL de permiss�o, adicionando a parte de par�metros
            $sql = "
				SELECT
					parametros
				FROM
					si_grupo_acao s
				WHERE
					ID_ACA = :idAcao AND
					ID_GRU = :idGrupo";
            $st = $this->getConexao()->prepare($sql);
            $st->bindValue(":idAcao", $acao);
            $st->bindValue(":idGrupo", $grupo);
            $st->execute();

            if ($result = $st->fetch()) {
                return $result['parametros'];
            } else {
                throw new ExceptionDAO("Voc� n�o tem permiss�o para acessar essa funcionalidade.");
            }
        } catch (ExceptionDAO $ed) {
            throw $ed;
        } catch (Exception $e) {
            $this->gerarExcecao($e, "Erro ao obter paramentro por a��o.");
        }
    }

    /**
     * Verifica se um usu�rio aceitou o termo de responsabilidade.
     *
     * @return bool
     */
    public function aceitouTermoResponsabilidade($idUsuario) {
        if (TOAluno::isMatriculaAluno($idUsuario)) {
            throw new ExceptionPermissao("Permiss�o negada.");
        } else {
            $dao = new DAOUsuarioServidor();
            return $dao->aceitouTermoResponsabilidade($idUsuario);
        }
    }

    /**
     * Registra a aceita��o do termo de responsabilidade de um usu�rio.
     */
    public function aceitarTermoResponsabilidade($idUsuario) {
        if (TOAluno::isMatriculaAluno($idUsuario)) {
            throw new ExceptionPermissao("Permiss�o negada.");
        } else {
            $dao = new DAOUsuarioServidor();
            return $dao->aceitarTermoResponsabilidade($idUsuario);
        }
    }

    /**
     * Consulta um usu�rio espec�fico.
     * @param int $idUsuario
     * @return TOUsuarioServidor
     */
    public function consultaUsuario($idUsuario) {
        if (TOAluno::isMatriculaAluno($idUsuario)) {
            $dao = new DAOUsuarioAluno();
            return $dao->consultar($idUsuario);
        } else {
            $dao = new DAOUsuarioServidor();
            return $dao->consultaUsuario($idUsuario);
        }
    }

     /**
      * Verifica se o idUsuario � um aluno para pesquisar o par�metro por GRUPO_ACAO
      * caso contr�rio procura pelo idUsuario
      * 
      * @param int $idUsuario
      * @param string $idAcao
      * @return string - Parametro
      */
    public function getParametroAcao($idUsuario, $idAcao) {
        if (TOAluno::isMatriculaAluno($idUsuario)) {
            return $this->getParametroPorAcao(TOUsuarioAluno::GRUPO_ALUNOS, $idAcao);
        } else {
            return $this->getParametroPorAcaoUsuario($idUsuario, $idAcao);
        }
    }
    /**
     * Obt�m uma array com os cursos de um usu�rio.
     *
     * @param TOUsuarioServidor $usuario
     * @return array [TOCurso]
     */
    public function listaCursosUsuario(TOUsuarioServidor $usuario) {
        if (TOAluno::isMatriculaAluno($usuario->getID())) {
            throw new ExceptionPermissao("Permiss�o negada.");
        } else {
            $dao = new DAOUsuarioServidor();
            return $dao->listaCursosUsuario($usuario);
        }
    }

    /**
     *
     * @param $idGrupo
     * @return unknown_type
     */
    public function consultaGrupo($idGrupo) {
        $dao = new DAOUsuarioServidor();
        return $dao->consultaGrupo($idGrupo);
    }

    /**
     *
     * @param $login
     * @param $email
     */
    public function consultarUsuarioLoginEmail($login, $email) {
        if (TOAluno::isMatriculaAluno($login)) {
            $dao = new DAOUsuarioAluno();
            return $dao->consultarPorLoginEmail($login, $email);
        } else {
            $dao = new DAOUsuarioServidor();
            return $dao->consultarPorLoginEmail($login, $email);
        }
    }

    /**
     *
     * @param $idUsuario
     * @param $idAcao
     * @param $parametro
     * @return unknown_type
     */
    public function logaOperacao($idUsuario, $acao, $parametro = null) {
        if (TOAluno::isMatriculaAluno($idUsuario)) {
            $dao = new DAOUsuarioAluno();
            $dao->logaOperacao($idUsuario, $acao, $_SERVER['REMOTE_ADDR']);
        } else {
            $dao = new DAOUsuarioServidor();
            $dao->logaOperacao($idUsuario, $acao, $parametro);
        }
    }

    /**
     * Exibe uma lista de usuarios do sistema
     *
     * @param $ordem
     * @param $inicio
     * @param $quantidade
     * @return unknown_type
     */
    public function listaUsuarios($ordem, $inicio, $quantidade) {
        $dao = new DAOUsuarioServidor();
        return $dao->listaUsuarios($ordem, $inicio, $quantidade);
    }

    /**
     * FIXME verificar este metodo. Consulta o(s) usuario(s) pelo nome
     * @param $usuario
     * @return unknown_type
     */
    public function consultaUsuarioNome(TOUsuarioServidor $usuario, $ordem, $inicio, $quantidade) {
        $dao = new DAOUsuarioServidor();
        return $dao->consultaUsuarioNome($usuario, $ordem, $inicio, $quantidade);
    }

    /**
     * Conta a quantidade de usuarios cadastrados
     * desde de que sejam maiores que os grupos (maiores que 10)
     *
     * @return unknown_type
     */
    public function contarUsuarios() {
        $dao = new DAOUsuarioServidor();
        return $dao->contarUsuarios();
    }

    /**
     * Conta a quantidade de usuarios cadastrados
     * desde de que sejam maiores que os grupos (maiores que 10)
     *
     * @return unknown_type
     */
    public function contarUsuarioNome(TOUsuarioServidor $usuario) {
        $dao = new DAOUsuarioServidor();
        return $dao->contarUsuarioNome($usuario);
    }

    /**
     * Lista os grupos de usu�rios existentes.
     *
     * @return unknown
     */
    public function listaGrupos() {
        $dao = new DAOUsuarioServidor();
        return $dao->listaGrupos();
    }

    /**
     *
     * @param $usuario
     * @return unknown_type
     */
    public function alteraAtivacao(TOUsuarioServidor $usuario) {
        $dao = new DAOUsuarioServidor();
        $dao->alteraAtivacao($usuario);
    }

    /**
     * Altera o estado de ativa��o de um grupo de usu�rios.
     * Normalmente "0" significa desativado e "1" significa
     * ativado.
     *
     * @param TOGrupo $grupo
     */
    public function alteraAtivacaoGrupo(TOGrupo $grupo) {
        $dao = new DAOUsuarioServidor();
        $dao->alteraAtivacaoGrupo($grupo);
    }

    /**
     * Remove um usu�rio do sistema.
     * A remo��o tem como efeito colateral
     * a remo��o do Log desse usu�rio, pedidos
     * de senha e associa��es de grupo.
     *
     * @param TOUsuarioServidor $usuario
     */
    public function removeUsuario(TOUsuarioServidor $usuario) {
        $dao = new DAOUsuarioServidor();
        $dao->removeUsuario($usuario);
    }

    /**
     * Remove um grupo do sistema.
     * A remo��o tem como efeito colateral
     * a remo��o da associa��o de usu�rios
     * com esse grupo e a remo��o das associ��es
     * de a��es com esse grupo.
     *
     * @param TOUsuarioServidor $usuario
     */
    public function removeGrupo(TOGrupo $grupo) {
        $dao = new DAOUsuarioServidor();
        $dao->removeGrupo($grupo);
    }

    /**
     * Cadastra um usu�rio.
     * @param TOUsuarioServidor $usuario
     */
    public function cadastraUsuario(TOUsuarioServidor $usuario) {
        $dao = new DAOUsuarioServidor();
        $dao->cadastraUsuario($usuario);
    }

    /**
     * Cadastra um usu�rio de aluno
     *
     * @param TOAluno $aluno
     */
    public function cadastrarUsuarioAluno(TOAluno $aluno) {
        $dao = new DAOUsuarioAluno();
        $dao->cadastrar($aluno);
    }

    /**
     * Edita o cadastro de um usu�rio.
     * @param TOUsuarioServidor $usuario
     */
    public function editaUsuario(TOUsuarioServidor $usuario) {
        $dao = new DAOUsuarioServidor();
        $dao->editaUsuario($usuario);
    }

    /**
     * Edita o cadastro de um usu�rio de aluno.
     *
     * @param TOAluno $aluno
     */
    public function editarUsuarioAluno(TOAluno $aluno) {
        $dao = new DAOUsuarioAluno();
        $dao->editar($aluno);
    }

    /**
     * Cadastra um usu�rio, sem cursos e sem grupos.
     * @param TOUsuarioServidor $usuario
     * @return int O id do usu�rio
     */
    public function cadastrarUsuarioSimples(TOUsuarioServidor $usuario) {
        $dao = new DAOUsuarioServidor();
        return $dao->cadastrarUsuarioSimples($usuario);
    }

    /**
     * Cadastra os grupos de um usu�rio.
     * @param $usuario
     */
    public function cadastrarGruposUsuario(TOUsuarioServidor $usuario) {
        $dao = new DAOUsuarioServidor();
        $dao->cadastrarGruposUsuario($usuario);
    }

    /**
     * Cadastra um novo grupo no banco de dados
     * incluindo suas permiss�es.
     *
     * @param TOGrupo $grupo
     */
    public function cadastraGrupo(TOGrupo $grupo) {
        $dao = new DAOUsuarioServidor();
        $dao->cadastraGrupo($grupo);
    }

    /**
     * Edita um grupo de usu�rios.
     * @param TOGrupo $grupo
     */
    public function editaGrupo(TOGrupo $grupo) {
        $dao = new DAOUsuarioServidor();
        $dao->editaGrupo($grupo);
    }

    /**
     *
     * @param $usuario
     * @return unknown_type
     */
    public function alteraSenhaUsuario(TOUsuario $usuario) {
        if (TOAluno::isMatriculaAluno($usuario->getID())) {
            $dao = new DAOUsuarioAluno();
            $senhaAtualReal = $dao->consultaSenhaAtual($usuario);
            if (md5($usuario->senha) != $senhaAtualReal) {
                throw new ExceptionDAO("Senha atual n�o confere.");
            }
            $dao->alterarSenha($usuario);
        } else {
            $dao = new DAOUsuarioServidor();
            $senhaAtualReal = $dao->consultaSenhaAtual($usuario);
            if (md5($usuario->senha) != $senhaAtualReal) {
                throw new ExceptionDAO("Senha atual n�o confere.");
            }
            $dao->alterarSenha($usuario);
        }
    }

    /**
     * Edita o e-mail do usu�rio.
     *
     * @param TOUsuario $usuario
     */
    public function editarEmailUsuario(TOUsuario $usuario) {
        if (TOAluno::isMatriculaAluno($usuario->getID())) {
            $dao = new DAOUsuarioAluno();
            $senhaAtualReal = $dao->consultaSenhaAtual($usuario);
            if (md5($usuario->senha) != $senhaAtualReal) {
                throw new ExceptionDAO("Senha atual n�o confere.");
            }
            $dao->editarEmail($usuario);
        } else {
            $dao = new DAOUsuarioServidor();
            $senhaAtualReal = $dao->consultaSenhaAtual($usuario);
            if (md5($usuario->senha) != $senhaAtualReal) {
                throw new ExceptionDAO("Senha atual n�o confere.");
            }
            $dao->editarEmail($usuario);
        }
    }

    /**
     * Obt�m a senha de um usu�rio.
     * A senha obtida � na verdade um hash MD5 da senha real.
     *
     * @param unknown_type $id_usuario
     * @return unknown
     */
    public function consultaSenhaAtual($id_usuario) {
        if (TOAluno::isMatriculaAluno($id_usuario)) {
            throw new ExceptionPermissao("Permiss�o negada.");
        } else {
            $dao = new DAOUsuarioServidor();
            return $dao->consultaSenhaAtual($id_usuario);
        }
    }

    /**
     *
     * @param $usuario
     * @param $posicao
     * @param $quantidade
     * @return unknown_type
     */
    public function getLogUsuario(TOUsuarioServidor $usuario, $posicao, $quantidade) {
        $dao = new DAOUsuarioServidor();
        return $dao->getLogUsuario($usuario, $posicao, $quantidade);
    }

    /**
     * Conta o total de logs de um usu�rio
     *
     * @param TOUsuarioServidor $usuario
     * @param int $limite
     * @return int
     */
    public function getCountLogUsuario(TOUsuarioServidor $usuario) {
        $dao = new DAOUsuarioServidor();
        return $dao->getCountLogUsuario($usuario);
    }

    /**
     *
     * @return unknown_type
     */
    public function listaPermissoes() {
        $dao = new DAOUsuarioServidor();
        return $dao->listaPermissoes();
    }

    /**
     * Cadastra um pedido de senha.
     *
     * @param $usuario
     * @param $url
     * @param $senha
     * @param $ip
     */
    public function cadastrarPedidoSenha($usuario, $url, $senha, $ip) {
        if (TOAluno::isMatriculaAluno($usuario->getID())) {
            $dao = new DAOUsuarioAluno();
            $dao->cadastrarPedidoSenha($usuario, $url, $senha, $ip);
        } else {
            $dao = new DAOUsuarioServidor();
            $dao->cadastrarPedidoSenha($usuario, $url, $senha, $ip);
        }
    }

    /**
     * Consulta um pedido de senha atrav�s do URL do pedido.
     *
     * O retorno do m�todo � na forma de um TOUsuarioServidor
     *
     * @param unknown_type $url
     * @return unknown
     */
    public function recuperarSenha($idUsuario, $url) {
        if (TOAluno::isMatriculaAluno($idUsuario)) {
            $dao = new DAOUsuarioAluno();
            return $dao->recuperarSenha($url);
        } else {
            $dao = new DAOUsuarioServidor();
            return $dao->recuperarSenha($url);
        }
    }

    /**
     * ...
     */
    public function contarUsuariosComSenhasFracas() {
        $dao = new DAOUsuarioServidor();
        return $dao->contarUsuariosComSenhasFracas();
    }

    /**
     * Recupera a lista de usu�rios que possuem senhas fracas
     *
     * @return array Lista de usu�rios
     */
    public function listaUsuariosComSenhasFracas($ordem, $inicio, $quantidade) {
        $dao = new DAOUsuarioServidor();
        return $dao->listaUsuarios($ordem, $inicio, $quantidade);
    }

    /**
     * Obt�m uma lista de usu�rios de um grupo.
     * @param $isGrupo O id do grupo.
     * @return array de TOUsuarioServidor. O array pode ser vazio.
     */
    public function listaMembrosGrupo($idGrupo) {
        $dao = new DAOUsuarioServidor();
        return $dao->listaMembrosGrupo($idGrupo);
    }

    /**
     *
     *
     * @param TOUsuarioServidor $usuario
     * @return array [TOCurso]
     */
    public function listarCursosSelecionaveisUsuario(TOUsuarioServidor $usuario) {
        if (TOAluno::isMatriculaAluno($usuario->getID())) {
            throw new ExceptionPermissao("Permiss�o negada.");
        } else {
            $dao = new DAOUsuarioServidor();
            return $dao->listarCursosSelecionaveisUsuario($usuario);
        }
    }

    /**
     * Obtem o(s) parametro de uma determinada a��o atrav�s de um usu�rio e a��o
     * 
     * @param int $acao o id da a��o
     * @return o parametro caso exista, null caso n�o exista paramentro
     * @throws ExceptionDAO caso n�o tenha o grupo e a��o
     */
    public function getParametroPorAcaoUsuario($idUsuario, $idAcao) {
        try {

            $sql = "SELECT parametros
                    FROM  si_usuario_grupo ug
                    JOIN si_grupo g ON (ug.ID_GRU = g.ID_GRU)
                    JOIN si_grupo_acao ga ON (g.ID_GRU = ga.ID_GRU)
                    WHERE ug.ID_USU = :idUsuario AND g.ATIVO_GRU = 1
                    AND (ga.ID_ACA = :idAcao OR ga.ID_ACA = :todasAcoes)";
            $st = $this->getConexao()->prepare($sql);
            $st->bindValue(":idUsuario", $idUsuario);
            $st->bindValue(":idAcao", $idAcao);
            $st->bindValue(":todasAcoes", TOAcao::TODAS_ACOES);
            $st->execute();

            if ($result = $st->fetch()) {
                return $result['parametros'];
            } else {
                throw new ExceptionDAO("Voc� n�o tem permiss�o para acessar essa funcionalidade.");
            }
            print_r($result);           
        } catch (ExceptionDAO $ed) {
            throw $ed;
        } catch (Exception $e) {
            $this->gerarExcecao($e, "Erro ao obter paramentro por a��o.");
        }
    }

}